package com.erp.framework.model.delegate;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.util.Collection;
import java.util.HashMap;

import javax.transaction.UserTransaction;

import com.erp.framework.SimpleConstants;
import com.erp.framework.exceptions.DeleteRecordException;
import com.erp.framework.exceptions.FindRecordException;
import com.erp.framework.model.criteria.SimpleBaseSrchCriteria;
import com.erp.framework.model.dao.ServiceLocator;
import com.erp.framework.model.dao.SimpleBaseDao;
import com.erp.framework.model.ejb.SimpleBaseSessionHome;
import com.erp.framework.model.ejb.SimpleBaseSessionRemote;
import com.erp.framework.model.pk.SimpleBasePk;
import com.erp.framework.model.vo.SimpleBaseVo;
import com.erp.framework.pagination.PageDataAccess;
import com.erp.framework.util.logger.Logger;

public class SimpleBaseDelegate implements Serializable, PageDataAccess, SimpleConstants {
	private Object contr = null;

	public SimpleBaseDelegate() {
	}

	public int getTotal(SimpleBaseVo model, SimpleBaseSrchCriteria crit) throws Exception {
		SimpleBaseSessionRemote remote = (SimpleBaseSessionRemote) getEjbManager();
		if (remote == null)
			throw new NullPointerException("Failed to obtain ejb object.");
		return remote.findTotal(model, crit);
	}

	public Collection getPage(SimpleBaseVo model, SimpleBaseSrchCriteria crit, int fetch_size, int start_idx) throws Exception {
		// return findByCriteria(model, crit, fetch_size, start_idx, loginUserCode);
		return findByCriteria(model, crit, fetch_size, start_idx);
	}

	public Collection findByCriteria(SimpleBaseVo model, SimpleBaseSrchCriteria criteria, int fetch_size, int start_idx)
			throws FindRecordException, Exception {
		SimpleBaseSessionRemote remote = null;
		try {
			remote = (SimpleBaseSessionRemote) getEjbManager();
			if (remote == null) {
				throw new NullPointerException();
			}
		} catch (Exception e) {
			Logger.debug(this, "error in findByCriteria :=" + e.getMessage());
			throw e;
		}
		return remote.findByCriteria(model, criteria, fetch_size, start_idx);
	}

	protected Class getDAOClass() {
		return null;
	}

	public SimpleBaseVo findMaster(Object obj) {
		SimpleBaseVo detail = null;
		try {
			// detail = getEjbManager().findMaster(obj);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
		}
		return detail;
	}

	// only used by masters
	// public SimpleBaseVo findByPrimaryKey(SimpleBaseVo model, SimpleBasePk pk) {
	//
	// SimpleBaseVo detail = null;
	// try {
	// detail = ((SimpleBaseSessionRemote) getEjbManager()).findByPrimaryKey(model, pk);
	// } catch (Exception e) {
	// Logger.logExceptions(this, e);
	// }
	// return detail;
	// }
	public SimpleBaseVo findByPrimaryKey(SimpleBaseVo model, SimpleBasePk pk) throws RemoteException, FindRecordException {
		SimpleBaseSessionRemote remote = null;
		SimpleBaseVo detail = null;
		try {
			remote = (SimpleBaseSessionRemote) getEjbManager();
			if (remote == null) {
				throw new NullPointerException();
			}
			detail = remote.findByPrimaryKey(model, pk);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new FindRecordException(e.getMessage());
		}
		return detail;
	}
	
	public SimpleBaseVo selectByPrimaryKey(SimpleBaseVo model, SimpleBasePk pk) throws FindRecordException {
		SimpleBaseSessionRemote remote = null;
		SimpleBaseVo vo = null;
		Connection conn = null;
		try {
			ServiceLocator srvLocator = ServiceLocator.getInstance();
			SimpleBaseDao dao = (SimpleBaseDao) model.getDaoType().newInstance();
			conn = srvLocator.getDSDBConnection();
			vo = dao.selectByPrimaryKey(model, pk, conn);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new FindRecordException(e.getMessage());
		} finally {
			try {
				conn.close();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
		return vo;
	}

	public Collection findByCriteria(SimpleBaseVo model, Object criteria) throws RemoteException, FindRecordException {
		SimpleBaseSessionRemote remote = null;
		try {
			remote = (SimpleBaseSessionRemote) getEjbManager();
			if (remote == null) {
				throw new NullPointerException();
			}
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new FindRecordException(e.getMessage());
		}
		return remote.findByCriteria(model, criteria);
	}
	
	public HashMap selectByCriteria(SimpleBaseVo model, SimpleBaseSrchCriteria criteria) throws FindRecordException {
		Connection conn = null;
		HashMap retHash = null;
		try {
			ServiceLocator srvLocator = ServiceLocator.getInstance();
			SimpleBaseDao dao = (SimpleBaseDao) model.getDaoType().newInstance();
			conn = srvLocator.getDSDBConnection();
			retHash = dao.selectByCriteria(model, criteria, conn);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new FindRecordException(e.getMessage());
		} finally {
			try {
				conn.close();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
		return retHash;
	}

	public SimpleBasePk createMaster(SimpleBaseVo model) throws Exception {
		SimpleBasePk pk = null;
		try {
			pk = ((SimpleBaseSessionRemote) getEjbManager()).createMaster(model);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw e;
		}
		return pk;
	}

	// public void updateBatch(Collection collection) throws Exception {
	//
	// try {
	// ((SimpleBaseSessionRemote) getEjbManager()).updateBatch(collection);
	// } catch (Exception e) {
	// Logger.logExceptions(this, e);
	// throw e;
	// }
	// }
	public void updateMaster(SimpleBaseVo model) throws Exception {
		try {
			((SimpleBaseSessionRemote) getEjbManager()).updateMaster(model);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw e;
		}
	}

	public void removeMaster(SimpleBaseVo model, SimpleBasePk pk) throws Exception {
		try {
			((SimpleBaseSessionRemote) getEjbManager()).removeMaster(model, pk);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw e;
		}
	}

	protected Object getEjbManager() {
		if (this.contr == null) {
			try {
				SimpleBaseSessionHome home = null;
				home = (SimpleBaseSessionHome) ServiceLocator.getInstance().getHome(SimpleConstants.SIMPLE_BASE_SESSION_EJB,
						SimpleBaseSessionHome.class);
				this.contr = home.create();
			} catch (java.lang.reflect.UndeclaredThrowableException ue) {
				Logger.logExceptions(this, ue);
				Logger.error(this, "getEjbManager(), error: " + ue.getUndeclaredThrowable());
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
		return this.contr;
	}

	public void removeSessionBean() {
		try {
			((SimpleBaseSessionRemote) getEjbManager()).remove();
		} catch (Exception e) {
			Logger.logExceptions(this, e);
		}
	}

	public boolean checkIfFormExists(SimpleBasePk pk) throws Exception {
		boolean rslt = false;
		Connection conn = null;
		try {
			conn = ServiceLocator.getInstance().getDSDBConnection();
			SimpleBaseDao dao = (SimpleBaseDao) getDAOClass().newInstance();
			rslt = dao.checkIfFormExists(pk, conn);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
		return rslt;
	}

	public Object sampleSelect(SimpleBaseVo model, Object obj) throws FindRecordException {
		Connection conn = null;
		Object retObj = null;
		try {
			ServiceLocator srvLocator = ServiceLocator.getInstance();
			SimpleBaseDao dao = (SimpleBaseDao) model.getDaoType().newInstance();
			conn = srvLocator.getDSDBConnection();
			// call your dao function here, for example:
			// retObj = dao.select(model, obj, conn);
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new FindRecordException(e.getMessage());
		} finally {
			try {
				conn.close();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
		return retObj;
	}

	public void sampleTransaction(SimpleBaseVo model, Object obj) throws DeleteRecordException, FindRecordException {
		ServiceLocator srvLocator = ServiceLocator.getInstance();
		SimpleBaseDao dao = null;
		Connection conn = null;
		SimpleBaseVo targetModel = null;
		try {
			conn = srvLocator.getDSDBConnection();
			dao = (SimpleBaseDao) model.getDaoType().newInstance();
			UserTransaction userTrans = srvLocator.getUserTransaction();
			userTrans.begin();
			try {
				// call your dao function here, for example:
				// dao.trans(model, conn);
				userTrans.commit();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
				srvLocator.userTransactionRollBack(userTrans);
				throw e;
			}
		} catch (Exception e) {
			Logger.logExceptions(this, e);
			throw new DeleteRecordException(e.getMessage());
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (Exception e) {
				Logger.logExceptions(this, e);
			}
		}
	}
}
